home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr30
/
dscrnv12.zip
/
DSCRNSAV.ASM
next >
Wrap
Assembly Source File
|
1993-05-04
|
8KB
|
250 lines
; Program dscrnsav.asm
; David Markovitch 1/12/90 and Peter Summers 21/9/91
IDEAL
SEGMENT CODE
ASSUME CS: CODE, DS: CODE
org 100h
start:
jmp init ; jump to initialization
shft_cnt equ 37 ; ticks between screen shifts 37 = 2 sec
id db "DSCRNSAV,DMPS"
maxcount dw 5465 ; timer ticks for delay 5465 = 5 min
old9_ofs dw ? ; old int 9 address
old9_seg dw ?
old1C_ofs dw ? ; old int 1C address
old1C_seg dw ?
old_tail dw ? ; keyboard buffer tail
off_flg db 0 ; 1 = disable blanking 0 = normal operation
scr_offst dw 0 ; offset for shifting screen
blank db 0 ; 1 = 'blank' screen 0 = normal screen
turn_on db 0 ; 1 = unblank screen 0 = nothing
count dw 0 ; tick counter for blanking
;------------------------------------------------------------------------------
proc new9 ; new int 9 (keyboard)
push es
push ds
push ax
push cs
pop ds
mov ax,40h
mov es,ax
mov ax,[word es: 1Ch] ; save keyboard buffer tail pointer
mov [old_tail],ax
pushf ; do bios keyboard handler
call [dword old9_ofs]
cmp [blank],0 ; check for blank screen
jne rest_scrn
mov [count],0 ; reset tick counter
jmp exit_9
rest_scrn: ; set flag to unblank screen
mov [turn_on],1
mov ax,[old_tail] ; restore tail pointer to remove key from buffer
mov [word es: 1Ch],ax
exit_9:
pop ax
pop ds
pop es
iret
endp new9
;------------------------------------------------------------------------------
proc new1C ; new int 1C (timer tick)
sti ; enable interrupts
push es
push ds
push dx
push ax
push cs
pop ds
mov ax,40h
mov es,ax
cmp [turn_on],0 ; check if flag set to restore screen
je if_blank ; jump to check for blank screen if flag not set
mov [turn_on],0 ; restore original video buffer start
mov [blank],0
mov ax,[word es: 4Eh] ; get bios video buffer start (bytes)
shr ax,1 ; convert to words
push ax
jmp do_crt ; set crt controller
if_blank:
cmp [off_flg],0 ; exit if disabled
jne exit_1C
cmp [blank],0 ; check if screen already blank
jne chk_shift ; if blank then jump to check if ready to shift
inc [count] ; screen not blank - check if time to blank
mov ax,[maxcount]
cmp [count],ax
jne exit_1C ; exit if not time to blank
mov [blank],1 ; set blank screen flag
jmp do_shift ; shift screen
chk_shift: ; if screen blank - shift every shft_cnt ticks
inc [count]
cmp [count],shft_cnt
jne exit_1C ; exit if not time to shift
do_shift:
mov ax,[scr_offst] ; get our video buffer offset (words)
add ax,1003 ; shift 1003 words
and ax,7FFh ; limit to first 4K of video buffer
mov [scr_offst],ax ; save our new video buffer offset
mov dx,[word es: 4Eh] ; get bios video buffer start (bytes)
shr dx,1 ; convert to words
add ax,dx ; add our offset
push ax
do_crt: ; set crt controller
mov dx,[es: 63h] ; crt controller base address
mov al,12 ; access register 12
out dx,al
inc dx
pop ax ; pop starting address
xchg ah,al
out dx,al ; write hi (start address) to register 12
dec dx
push ax ; push starting address
mov al,13 ; access register 13
out dx,al
inc dx
pop ax ; pop starting address
xchg ah,al
out dx,al ; write lo (start address) to register 13
mov [count],0 ; reset tick counter
exit_1C:
pop ax
pop dx
pop ds
pop es
jmp [dword cs: old1C_ofs]
endp new1C
;------------------------------------------------------------------------------
init_junk:
load_msg db 13,10,"Dscrnsav screen saver resident, v1.2"
db " by David Markovich and Peter Summers",13,10
db " SYNTAX: dscrnsav [delay], 0 disables,"
db " 1-9 re-enables, default=5",13,10,10,"$"
dsabl_msg db 13,10,"Dscrnsav disabled",13,10,"$"
enabl_msg db 13,10,"Dscrnsav enabled",13,10,"$"
err1_msg db 13,10,"Invalid command line parameter",13,10,"$"
err2_msg db 13,10,"Dscrnsav not resident",13,10,"$"
init: ; initialization
mov si,81h
mov dx,offset err1_msg ; "Invalid command line parameter"
parse_loop: ; check for number on command line
lodsb
cmp al," "
je parse_loop ; skip spaces
cmp al,13
je end_parse ; jump if no parameter
cmp al,"9"
jg out_err ; invalid parameter
cmp al,"0"
jl out_err ; invalid parameter
cmp al,"0"
jne set_time
mov [off_flg],1 ; set disable flag
set_time:
mov ah,0
sub al,"0"
mov bx,1093
mul bx
mov [maxcount],ax
end_parse:
cld ; search for a previous copy
mov [word start],0 ; fingerprint
mov bx,0 ; bx = start segment
mov ax,cs ; ax = current segment
cmp ax,0A000h ; Assume first load if running in high memory.
jae no_copies
chk_prev:
inc bx ; increment segment
cmp ax,bx ; check if equals current segment
jne next
mov bx,0A000h ; if yes, move search to high memory
next:
cmp bx,0FFFFh ; end search if end of memory reached
je no_copies
mov es,bx
mov si,offset start
mov di,si
mov cx,16 ; compare first 16 bytes of each segment
repe cmpsb
jne chk_prev ; repeat if no match
mov ax,[maxcount] ; copy found - set time for activation
mov [es: maxcount],ax
mov al,[off_flg] ; change enable/disable flag
mov [es: off_flg],al
mov [es: count],0 ; reset tick count
mov dx,offset enabl_msg ; "Dscrnsav enabled"
cmp al,0
je out_msg ; copy enabled - errorlevel = 0
mov dx,offset dsabl_msg ; "Dscrnsav disabled"
mov al,0 ; errorlevel = 0
jmp out_msg ; copy disabled
no_copies:
mov dx,offset err2_msg ; "Dscrnsav not resident"
cmp [off_flg],0
je install ; ok to install
out_err:
mov al,1
out_msg:
mov ah,9 ; display message
int 21h
mov ah,4Ch ; terminate with errorlevel = al
int 21h
install: ; make program resident
mov ax,3509H ; get old int 9 address
int 21H
mov ax,es
mov [old9_seg],ax ; save old int 9 address (keyboard)
mov [old9_ofs],bx
mov ax,351CH ; get old int 1C address (timer tick)
int 21H
mov ax,es
mov [old1C_seg],ax ; save old int 1C address
mov [old1C_ofs],bx
mov dx,offset new9 ; set int 9 to point to our code
mov ax,2509H
int 21H
mov dx,offset new1C ; set int 1C to point to our code
mov ax,251CH
int 21H
mov dx,offset load_msg ; "Dscrnsav loaded"
mov ah,9
int 21h ; display message
mov dx,(init_junk - start + 256 + 16)/16
mov ax,3100H ; terminate and stay resident
int 21H
ends
end start